package com.reactim.user.controller;

import com.reactim.user.entity.FriendRequest;
import com.reactim.user.service.FriendRequestService;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 好友请求控制器
 */
@Slf4j
@RestController
@RequestMapping("/api/friend-requests")
@RequiredArgsConstructor
public class FriendRequestController {
    
    private final FriendRequestService friendRequestService;
    
    /**
     * 发送好友请求
     */
    @PostMapping
    public ResponseEntity<FriendRequestResponse> sendFriendRequest(
            @Valid @RequestBody SendFriendRequestDto request) {
        
        FriendRequest friendRequest = friendRequestService.sendFriendRequest(
                request.getFromUserId(), 
                request.getToUserId(), 
                request.getMessage()
        );
        
        FriendRequestResponse response = convertToResponse(friendRequest);
        
        log.info("好友请求发送成功: fromUserId={}, toUserId={}", 
                request.getFromUserId(), request.getToUserId());
        
        return ResponseEntity.ok(response);
    }
    
    /**
     * 接受好友请求
     */
    @PostMapping("/{requestId}/accept")
    public ResponseEntity<Void> acceptFriendRequest(
            @PathVariable Long requestId,
            @Valid @RequestBody ProcessRequestDto request) {
        
        friendRequestService.acceptFriendRequest(requestId, request.getUserId());
        
        log.info("好友请求已接受: requestId={}, userId={}", requestId, request.getUserId());
        
        return ResponseEntity.ok().build();
    }
    
    /**
     * 拒绝好友请求
     */
    @PostMapping("/{requestId}/reject")
    public ResponseEntity<Void> rejectFriendRequest(
            @PathVariable Long requestId,
            @Valid @RequestBody RejectRequestDto request) {
        
        friendRequestService.rejectFriendRequest(requestId, request.getUserId(), request.getReason());
        
        log.info("好友请求已拒绝: requestId={}, userId={}", requestId, request.getUserId());
        
        return ResponseEntity.ok().build();
    }
    
    /**
     * 取消好友请求
     */
    @PostMapping("/{requestId}/cancel")
    public ResponseEntity<Void> cancelFriendRequest(
            @PathVariable Long requestId,
            @Valid @RequestBody ProcessRequestDto request) {
        
        friendRequestService.cancelFriendRequest(requestId, request.getUserId());
        
        log.info("好友请求已取消: requestId={}, userId={}", requestId, request.getUserId());
        
        return ResponseEntity.ok().build();
    }
    
    /**
     * 获取收到的好友请求
     */
    @GetMapping("/received")
    public ResponseEntity<PageResponse<FriendRequestResponse>> getReceivedRequests(
            @RequestParam Long userId,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "20") int size) {
        
        Pageable pageable = PageRequest.of(page, size);
        Page<FriendRequest> requestPage = friendRequestService.getReceivedRequests(userId, pageable);
        
        List<FriendRequestResponse> responses = requestPage.getContent().stream()
                .map(this::convertToResponse)
                .toList();
        
        PageResponse<FriendRequestResponse> pageResponse = new PageResponse<>();
        pageResponse.setContent(responses);
        pageResponse.setTotalElements(requestPage.getTotalElements());
        pageResponse.setTotalPages(requestPage.getTotalPages());
        pageResponse.setCurrentPage(page);
        pageResponse.setPageSize(size);
        
        return ResponseEntity.ok(pageResponse);
    }
    
    /**
     * 获取发送的好友请求
     */
    @GetMapping("/sent")
    public ResponseEntity<PageResponse<FriendRequestResponse>> getSentRequests(
            @RequestParam Long userId,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "20") int size) {
        
        Pageable pageable = PageRequest.of(page, size);
        Page<FriendRequest> requestPage = friendRequestService.getSentRequests(userId, pageable);
        
        List<FriendRequestResponse> responses = requestPage.getContent().stream()
                .map(this::convertToResponse)
                .toList();
        
        PageResponse<FriendRequestResponse> pageResponse = new PageResponse<>();
        pageResponse.setContent(responses);
        pageResponse.setTotalElements(requestPage.getTotalElements());
        pageResponse.setTotalPages(requestPage.getTotalPages());
        pageResponse.setCurrentPage(page);
        pageResponse.setPageSize(size);
        
        return ResponseEntity.ok(pageResponse);
    }
    
    /**
     * 获取待处理请求数量
     */
    @GetMapping("/pending-count")
    public ResponseEntity<PendingCountResponse> getPendingRequestCount(@RequestParam Long userId) {
        long count = friendRequestService.getPendingRequestCount(userId);
        
        PendingCountResponse response = new PendingCountResponse();
        response.setCount(count);
        
        return ResponseEntity.ok(response);
    }
    
    /**
     * 检查是否可以发送好友请求
     */
    @GetMapping("/can-send")
    public ResponseEntity<CanSendResponse> canSendFriendRequest(
            @RequestParam Long fromUserId,
            @RequestParam Long toUserId) {
        
        boolean canSend = friendRequestService.canSendFriendRequest(fromUserId, toUserId);
        
        CanSendResponse response = new CanSendResponse();
        response.setCanSend(canSend);
        
        return ResponseEntity.ok(response);
    }
    
    /**
     * 转换为响应对象
     */
    private FriendRequestResponse convertToResponse(FriendRequest request) {
        FriendRequestResponse response = new FriendRequestResponse();
        response.setId(request.getId());
        response.setFromUserId(request.getFromUserId());
        response.setToUserId(request.getToUserId());
        response.setMessage(request.getMessage());
        response.setStatus(request.getStatus().name());
        response.setRejectReason(request.getRejectReason());
        response.setCreatedAt(request.getCreatedAt());
        response.setUpdatedAt(request.getUpdatedAt());
        response.setProcessedAt(request.getProcessedAt());
        response.setExpiredAt(request.getExpiredAt());
        return response;
    }
    
    // DTO classes
    
    @Data
    public static class SendFriendRequestDto {
        @NotNull(message = "发送者用户ID不能为空")
        private Long fromUserId;
        
        @NotNull(message = "接收者用户ID不能为空")
        private Long toUserId;
        
        @Size(max = 200, message = "请求消息不能超过200个字符")
        private String message;
    }
    
    @Data
    public static class ProcessRequestDto {
        @NotNull(message = "用户ID不能为空")
        private Long userId;
    }
    
    @Data
    public static class RejectRequestDto {
        @NotNull(message = "用户ID不能为空")
        private Long userId;
        
        @Size(max = 200, message = "拒绝原因不能超过200个字符")
        private String reason;
    }
    
    @Data
    public static class FriendRequestResponse {
        private Long id;
        private Long fromUserId;
        private Long toUserId;
        private String message;
        private String status;
        private String rejectReason;
        private LocalDateTime createdAt;
        private LocalDateTime updatedAt;
        private LocalDateTime processedAt;
        private LocalDateTime expiredAt;
    }
    
    @Data
    public static class PageResponse<T> {
        private List<T> content;
        private long totalElements;
        private int totalPages;
        private int currentPage;
        private int pageSize;
    }
    
    @Data
    public static class PendingCountResponse {
        private long count;
    }
    
    @Data
    public static class CanSendResponse {
        private boolean canSend;
    }
}